<%
'######################################################################
'## ab.key.asp
'## -------------------------------------------------------------------
'## Feature     :   AspBox Dictionary Class
'## Version     :   v1.0
'## Author      :   Lajox(lajox@19www.com)
'## Update Date :   2015/12/05 14:48
'## Description :   AspBox字典库操作类
'######################################################################

Class Cls_AB_Key

	Private o_dict
	Public Items

	Private Sub Class_Initialize()
		Set Items = Server.CreateObject(AB.dictName)
	End Sub

	Private Sub Class_Terminate()
		Set Items = Nothing
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Key.New 方法
	'# @syntax: Set key = AB.Key.New
	'# @return: Object (ASP对象)
	'# @dowhat: 建立字典操作对象, 创建一个 Cls_AB_Key 对象
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# none
	'------------------------------------------------------------------------------------------

	Public Function [New]()
		Set [New] = New Cls_AB_Key
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.Key.Count 属性
	'# @syntax: n = AB.Key.Count
	'# @return: Integer (整型)
	'# @dowhat: 获取存储的key子项个数
	'--DESC------------------------------------------------------------------------------------
	'# @param n : Variant(已定义的变量)
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Key.Clear '清空数据
	'# AB.Key("a") = "test123"
	'# AB.Key("b") = AB.Dict
	'# AB.C.PrintCn AB.Key.Count '计算个数: 2
	'------------------------------------------------------------------------------------------

	Public Property Get Count()
		Count = Items.Count
	End Property

	'------------------------------------------------------------------------------------------
	'# AB.Key.Item 方法
	'# @syntax: AB.Key.Item(str)[ = value]
	'# @alias:  AB.Key(str)[ = value]
	'# @return: Integer (整型)
	'# @dowhat: 设置或获取字典项值
	'--DESC------------------------------------------------------------------------------------
	'# @param str :  String (字符串) 存储的键名
	'# @param value(可选) : Any (任意值) 存储值
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Key("a") = "test123" '等效于：AB.Key("a").Set "test123"
	'# AB.C.PrintCn AB.Key("a") '字符串数据可以直接获取
	'# AB.Key("b") = AB.Dict '存储对象
	'# AB.Trace AB.Key("b").Value '读取对象值一般用 AB.Key(s).Value 方法获取
	'------------------------------------------------------------------------------------------

	Public Default Property Get Item(ByVal k)
		If Not IsObject(Items(k)) Then
			Set Items(k) = New Cls_AB_Key_Info
			Items(k).Key = k
		End If
		Set Item = Items(k)
	End Property

	Public Property Let Item(ByVal k, ByVal v)
		Add k, v
	End Property

	'------------------------------------------------------------------------------------------
	'# AB.Key.Keys 属性
	'# @syntax: n = AB.Key.Keys
	'# @return: Array (数组)
	'# @dowhat: 返回一个包含所有项键名的数组
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Key.Add "a","abc123"
	'# AB.Key("b") = Array()
	'# AB.Key("c") = AB.Dict
	'# AB.C.PrintCn AB.Key.Count '计算项个数
	'# Dim a : a = AB.Key.Keys() '返回一个包含所有项键名的数组
	'# AB.C.PrintCn "所有子项键名："
	'# Dim i
	'# For Each i In a
	'# 	AB.C.PrintCn i
	'# Next
	'# Dim k : k = "a"
	'# AB.C.PrintCn "子项键名为 "& k &" 的值："
	'# AB.Trace AB.Key(k).Value
	'------------------------------------------------------------------------------------------

	Public Property Get Keys()
		Dim i, n, a : a = Array()
		n = 0
		For Each i In Items
			Redim Preserve a(n)
			a(n) = Items(i).Key
			n = n+1
		Next
		Keys = a
	End Property

	'------------------------------------------------------------------------------------------
	'# AB.Key.Values 方法
	'# @syntax: AB.Key.Values
	'# @return: Arrray
	'# @dowhat: 获取字典所有值，返回一个数组
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Key.New
	'# key.add "a","abc123"
	'# key("b") = Array()
	'# key("c") = AB.Dict
	'# Dim values : values = key.Values
	'# AB.Trace values '打印所有值
	'------------------------------------------------------------------------------------------

	Public Function Values()
		Dim f, a : a = Array()
		AB.Use "A"
		If Not AB.C.IsNul(Items) Then
			For Each f In Items
				a = AB.A.Push( a, Items(f).Value )
			Next
		End If
		Values = a
	End Function
	
	'------------------------------------------------------------------------------------------
	'# AB.Key.Data 方法
	'# @syntax: AB.Key.Data
	'# @return: Dictionary 字典对象
	'# @dowhat: 获取字典所有值，返回一个字典
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Key.New
	'# key.add "a","abc123"
	'# key("b") = Array()
	'# key("c") = AB.Dict
	'# Dim values : values = key.Values
	'# AB.Trace values '打印所有值（数组）
	'# AB.Trace key.Items '所有字典元素对象
	'# AB.Trace key.Data '所有字典元素真实值（字典）
	'------------------------------------------------------------------------------------------
	Public Function Data()
		Dim f, d : Set d = AB.C.Dict()
		If AB.C.isDict(Items) Then
			For Each f In Items
				If Lcase(TypeName(Items(f))) = "cls_ab_key_info" Then
					d.Add f, Items(f).Value
				Else
					d.Add f, Items(f)
				End If
			Next
		End If
		Set Data = d
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.Key.Add 方法
	'# @syntax: AB.Key.Add str, value
	'# @alias:  AB.Key.Set str, value 或 AB.Key(str).Set value 或 AB.Key(str).Add value
	'# @return: Void
	'# @dowhat: 存储键名为str的值到字典里
	'--DESC------------------------------------------------------------------------------------
	'# @param str : String (字符串) 存储的键名
	'# @param value(可选) : Any (任意值) 存储值
	'--DEMO------------------------------------------------------------------------------------
	'# AB.Key("a").Add "test123" '等同于：AB.Key("a").Set "test123"
	'# AB.C.PrintCn AB.Key("a")
	'# AB.Trace AB.Key("a").Value
	'------------------------------------------------------------------------------------------

	Public Sub Add(ByVal k, ByVal v)
		If IsNull(k) Then k = ""
		If Not IsObject(Items(k)) Then
			Set Items(k) = New Cls_AB_Key_Info
		End If
		Items(k).Key = k
		Items(k).Value = v
	End Sub
	Public Sub [Set](ByVal k, ByVal v) : Add k, v : End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Key.Remove 方法
	'# @syntax: AB.Key.Remove str
	'# @alias:  AB.Key.Del str
	'# @return: Void
	'# @dowhat: 从字典里删除键名为str项
	'--DESC------------------------------------------------------------------------------------
	'# @param str : String (字符串) 键名
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Key.New
	'# key.add "a","abc123"
	'# key("b") = Array()
	'# key("c") = AB.Dict
	'# AB.Trace key("b")
	'# AB.Trace key("c").Value
	'# key.Del "c"
	'# If Not key.Items.Exists("c") Then AB.C.PrintCn "项 c 已被删除"
	'# AB.C.PrintCn "共" & key.Count & "项"
	'# Dim i
	'# For Each i In key.Keys
	'# 	AB.C.PrintCn "子项键名为 "& i &" 的值："
	'# 	AB.Trace key(i).Value
	'# Next
	'------------------------------------------------------------------------------------------

	Public Sub Remove(ByVal k)
		Dim f : f = k
		If Items.Exists(f) Then
			If Lcase(TypeName(Items(f))) = "cls_ab_key_info" Then Items(f).Clear()
			Items.Remove(f)
		End IF
	End Sub
	Public Sub Del(ByVal k) : Remove k : End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Key.Clear 方法
	'# @syntax: AB.Key.Clear
	'# @alias:  AB.Key.RemoveAll
	'# @return: Void
	'# @dowhat: 清空所有字典项
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Key.New
	'# key.add "a","abc123"
	'# key("b") = Array()
	'# key("c") = AB.Dict
	'# key.Clear
	'# AB.Trace key.Count '计算项个数
	'------------------------------------------------------------------------------------------

	Public Sub Clear()
		Dim f
		For Each f In Items
			If Lcase(TypeName(Items(f))) = "cls_ab_key_info" Then Items(f).Clear()
			If IsObject(Items(f)) Then Set Items(f) = Nothing Else Items(f) = Empty
		Next
		Items.RemoveAll
	End Sub
	Public Sub RemoveAll() : Clear() : End Sub

	'------------------------------------------------------------------------------------------
	'# AB.Key.Sort 方法
	'# @syntax: AB.Key.Sort()
	'# @return: Dictionary对象
	'# @dowhat: 对字典单元从低到高进行排序
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Lib("key").New
	'# key.add "a", 1
	'# key.add "b", 7
	'# key.add "c", "a"
	'# key.add "d", "d"
	'# key.add "e", "c"
	'# key.add "f", 4
	'# 'ab.trace key.values '打印所有值： 1, 7, a, d, c, 4
	'# ab.trace key.Data '打印所有值列： [ a=>1, b=>7, c=>a, d=>d, e=>c, f=>4 ]
	'# ab.trace key.Sort.Data '打印进行rSort排序后的值列表： [ 0=>1, 1=>4, 2=>7, 3=>a, 4=>c, 5=>d ]
	'------------------------------------------------------------------------------------------

	Public Function Sort()
		On Error Resume Next
		Dim i, a : a = Me.Values
		a = AB.A.Sort(a)
		Me.Clear '清空数据
		For i=0 To UBound(a)
			'Me(i) = a(i)
			Me.Add i, a(i)
		Next
		Set Sort = Me
		On Error Goto 0
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.Key.rSort 方法
	'# @syntax: AB.Key.rSort()
	'# @return: Arrray
	'# @dowhat: 对字典单元从高到低进行排序
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Lib("key").New
	'# key.add "a", 1
	'# key.add "b", 7
	'# key.add "c", "a"
	'# key.add "d", "d"
	'# key.add "e", "c"
	'# key.add "f", 4
	'# 'ab.trace key.values '打印所有值： 1, 7, a, d, c, 4
	'# ab.trace key.Data '打印所有值列： [ a=>1, b=>7, c=>a, d=>d, e=>c, f=>4 ]
	'# ab.trace key.rSort.Data '打印进行rSort排序后的值列表： [ 0=>d, 1=>c, 2=>a, 3=>7, 4=>4, 5=>1 ]
	'------------------------------------------------------------------------------------------

	Public Function rSort()
		On Error Resume Next
		Dim i, a : a = Me.Values
		a = AB.A.rSort(a)
		Me.Clear '清空数据
		For i=0 To UBound(a)
			'Me(i) = a(i)
			Me.Add i, a(i)
		Next
		Set rSort = Me
		On Error Goto 0
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.Key.kSort 方法
	'# @syntax: AB.Key.kSort()
	'# @return: Dictionary对象
	'# @dowhat: 对字典单元按键名从低到高进行排序
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Lib("key").New
	'# key.add "a", 1
	'# key.add "c", "a"
	'# key.add "e", "c"
	'# key.add "b", 7
	'# key.add "d", "d"
	'# key.add "f", 4
	'# 'ab.trace key.Keys '打印所有Key： a, c, e, b, d, f
	'# ab.trace key.Data '打印所有值列： [ a=>1, c=>a, e=>c, b=>7, d=>d, f=>4 ]
	'# ab.trace key.kSort.Data '打印进行kSort排序后的值列表： [ a=>1, b=>7, c=>a, d=>d, e=>c, f=>4 ]
	'------------------------------------------------------------------------------------------

	Public Function kSort()
		On Error Resume Next
		Dim i, a, d : a = Me.Keys
		a = AB.A.Sort(a)
		Set d = AB.C.Clone( Me.Items ) '克隆对象
		Me.Clear '清空数据
		For i=0 To UBound(a)
			If Lcase(TypeName( d.Item(a(i)) )) = "cls_ab_key_info" Then
				'Me(a(i)) = d.Item(a(i)).Value
				Me.Add a(i), d.Item(a(i)).Value
			Else
				Me.Add a(i), d.Item(a(i))
			End If
		Next
		Set kSort = Me
		On Error Goto 0
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.Key.krSort 方法
	'# @syntax: AB.Key.krSort()
	'# @return: Arrray
	'# @dowhat: 对字典单元按键名从高到低进行排序
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Lib("key").New
	'# key.add "a", 1
	'# key.add "c", "a"
	'# key.add "e", "c"
	'# key.add "b", 7
	'# key.add "d", "d"
	'# key.add "f", 4
	'# 'ab.trace key.Keys '打印所有Key： a, c, e, b, d, f
	'# ab.trace key.Data '打印所有值列： [ a=>1, b=>7, c=>a, d=>d, e=>c, f=>4 ]
	'# ab.trace key.krSort.Data '打印进行krSort排序后的值列表： [ f=>4, e=>c, d=>d, c=>a, b=>7, a=>1 ]
	'------------------------------------------------------------------------------------------

	Public Function krSort()
		On Error Resume Next
		Dim i, a, d : a = Me.Keys
		a = AB.A.rSort(a)
		Set d = AB.C.Clone( Me.Items ) '克隆对象
		Me.Clear '清空数据
		For i=0 To UBound(a)
			If Lcase(TypeName( d.Item(a(i)) )) = "cls_ab_key_info" Then
				'Me(a(i)) = d.Item(a(i)).Value
				Me.Add a(i), d.Item(a(i)).Value
			Else
				Me.Add a(i), d.Item(a(i))
			End If
		Next
		Set krSort = Me
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.Key.aSort 方法
	'# @syntax: AB.Key.aSort()
	'# @return: Arrray
	'# @dowhat: 对字典单元按值从低到高进行排序并保留原键名
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Lib("key").New
	'# key.add "a", 1
	'# key.add "c", "a"
	'# key.add "e", "c"
	'# key.add "b", 7
	'# key.add "d", "d"
	'# key.add "f", 4
	'# 'ab.trace key.Keys '打印所有Key： a, c, e, b, d, f
	'# ab.trace key.Data '打印所有值列： [ a=>1, c=>a, e=>c, b=>7, d=>d, f=>4 ]
	'# ab.trace key.aSort.Data '打印进行aSort排序后的值列表： [ a=>1, f=>4, b=>7, c=>a, e=>c, d=>d ]
	'------------------------------------------------------------------------------------------

	Public Function aSort()
		On Error Resume Next
		Me.aSort__(0)
		Set aSort = Me
		On Error Goto 0
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.Key.arSort 方法
	'# @syntax: AB.Key.arSort()
	'# @return: Arrray
	'# @dowhat: 对字典单元按值从高到低进行排序并保留原键名
	'--DESC------------------------------------------------------------------------------------
	'# @param: none
	'--DEMO------------------------------------------------------------------------------------
	'# Dim key : Set key = AB.Lib("key").New
	'# key.add "a", 1
	'# key.add "c", "a"
	'# key.add "e", "c"
	'# key.add "b", 7
	'# key.add "d", "d"
	'# key.add "f", 4
	'# 'ab.trace key.Keys '打印所有Key： a, c, e, b, d, f
	'# ab.trace key.Data '打印所有值列： [ a=>1, c=>a, e=>c, b=>7, d=>d, f=>4 ]
	'# ab.trace key.arSort.Data '打印进行arSort排序后的值列表： [ d=>d, e=>c, c=>a, b=>7, f=>4, a=>1 ]
	'------------------------------------------------------------------------------------------

	Public Function arSort()
		On Error Resume Next
		Me.aSort__(1)
		Set arSort = Me
		On Error Goto 0
	End Function

	Public Function aSort__(n)
		On Error Resume Next
		Dim i, f, a, b, c, e, data : a = Array() : Set b = AB.C.Dict() : Set c = AB.C.Dict() : Set data = Me.Data()
		n = CLng(n)
		If Not AB.C.IsNul(data) Then
			For Each i In data
				If IsObject(data(i)) Or IsArray(data(i)) Then
					c.Add i, data(i)
				Else
					b.Add i, data(i)
				End If
			Next
			'将字典数据暂存寄放于数组
			For Each i In b
				e = Array( i, b(i) )
				a = AB.A.Push( a, e )
			Next
			Dim check : check = True
			If Not AB.C.isNul(a) Then
				Do Until check = False
					check = False
					For i = 0 to UBound(a)-1
						If n = 0 Then
							If a(i)(1) > a(i+1)(1) Then
								f = a(i)
								a(i) = a(i+1)
								a(i+1) = f
								check = True
							End If
						Else
							If a(i)(1) < a(i+1)(1) Then
								f = a(i)
								a(i) = a(i+1)
								a(i+1) = f
								check = True
							End If
						End If
					Next
				Loop
				b.RemoveAll()
				Set b = AB.C.Dict()
				For Each i In a
					b.Add i(0), i(1)
				Next
			End If
		End If
		Me.Clear()
		For Each i In b
			If Lcase(TypeName( b(i) )) = "cls_ab_key_info" Then
				'Me(i) = b(i).Value
				Me.Add i, b(i).Value
			Else
				Me.Add i, b(i)
			End If
		Next
		For Each i In c
			If Lcase(TypeName( c(i) )) = "cls_ab_key_info" Then
				'Me(i) = c(i).Value
				Me.Add i, c(i).Value
			Else
				Me.Add i, c(i)
			End If
		Next
		Set c = Nothing
		On Error Goto 0
	End Function

End Class

Class Cls_AB_Key_Info

	Private o_value
	Public Key

	Private Sub Class_Initialize() : End Sub
	Private Sub Class_Terminate: Clear(): End Sub

	Public Sub Clear()
		If IsObject(o_value) Then Set o_value = Nothing
	End Sub

	Public Property Let [Value](ByVal v)
		[Set] v
	End Property

	Public Default Property Get [Value]()
		If IsObject(o_value) Then
			Select Case TypeName(o_value)
				Case "Recordset"
					Set [Value] = o_value.Clone
				Case Else
					Set [Value] = o_value
			End Select
		Else
			[Value] = o_value
		End If
	End Property

	Public Sub [Set](ByVal v)
		If IsObject(v) Then
			Select Case TypeName(v)
				Case "Recordset"
					Set o_value = v.Clone
				Case Else
					Set o_value = v
			End Select
		Else
			o_value = v
		End If
	End Sub
	Public Sub Add(ByVal v) : [Set] v : End Sub

End Class
%>